package com.trgzs.bate.common.aspect;

import com.trgzs.bate.common.response.BaseResult;
import com.trgzs.bate.common.utils.RequestIdUtil;
import com.trgzs.bate.common.utils.ServletUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * @Author: dongl
 * @Email: dong980514280@gmail.com
 * @Create: 2025-01-07 21:30:53
 * @PS
 **/
@Aspect
@Component
@Slf4j
@Order(-10)
public class ControllerRequestAspect {

    private long startTime = 0;
    private long endTime = 0;

    @Pointcut(value = "execution(* com.trgzs.bate..*.api..*(..))")
    public void controllerPoint() {}

    @Around("controllerPoint()")
    public Object doControllerPointAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String requestId = UUID.randomUUID().toString();
        MDC.put("requestId", requestId);
        Object result = null;
        try {
            result = joinPoint.proceed();
        } finally {
//            MDC.remove("requestId");
        }
        return result;
    }

    /**
     * 请求前置通知
     */
    @Before("controllerPoint()")
    public void beforLogger(JoinPoint joinPoint) {
        HttpServletRequest httpServletRequest = ServletUtils.getRequest();
        String requestId = httpServletRequest.getHeader("requestId");
        if (StringUtils.isBlank(requestId)) {
            RequestIdUtil.setRequestId();
        } else {
            RequestIdUtil.setRequestId(requestId);
        }
        startTime = System.currentTimeMillis();
    }

    /**
     * 请求后置通知，请求完成会进入到这个方法
     *
     * @param result 响应结果json
     */
    @AfterReturning(value = "controllerPoint()", returning = "result")
    public void afterReturningLogger(Object result) {
        endTime = System.currentTimeMillis();
        long t = endTime - startTime;
        if(result instanceof BaseResult<?>) {
            ((BaseResult<?>) result).setDurationMs(t);
            log.debug("执行时间{}ms", t);
        }
        RequestIdUtil.clear();
    }
}